<template>
  <div class="fit row no-wrap justify-between items-start">
    <qx-tree v-if="!isXS" :loading="loading" :options="orgTree" :props="props"
             classes="q-col-125rem bg-white shadow-1 full-height" @change="treeChange"></qx-tree>
    <qx-table :option="formOption" :remoteData="remoteData" class="col q-ml-md">
      <template v-slot:top>
        <qx-form v-model="searchForm" :option="searchOption" isSearch @submit="startSearch"></qx-form>
      </template>
      <template v-slot:menuLeft="{ selected }">
        <q-btn v-auth="['memberUser:save']" color="primary" icon="add" unelevated @click="handleCreate">
          {{ $t('Add') }}
        </q-btn>
        <q-btn v-auth="['memberUser:update']" :disable="isDisable(selected)" icon="mdi-square-edit-outline" outline
               text-color="primary" @click="handleUpdate(selected[0])">
          {{ $t('Edit') }}
        </q-btn>
        <q-btn v-auth="['memberUser:save', 'memberUser:update']" :disable="isDisable(selected)" :loading="roleLoading"
               outline text-color="primary" @click="handleRole(selected[0])">
          {{ $t('SystemCore.AssignRole') }}
        </q-btn>
        <q-btn v-auth="['memberUser:delete']" :disable="isDisable(selected)" icon="delete" outline text-color="primary"
               @click="handleDelete(selected[0])">
          {{ $t('Del') }}
        </q-btn>
      </template>
      <template v-slot:loginName="{ row }">
        <q-link @click="handleRole(row)">{{ row.loginName }}</q-link>
      </template>
    </qx-table>
  </div>
  <qx-page v-model="pageVisible" :fullHeight="readonly" :header="`${$t('SystemCore.AssignUserRole')}`"
           :menuBtn="!readonly" @confirm="submitRole">
    <DistributionRoles ref="UserRole" v-model="pageVisible" v-model:list="rolesList" v-model:rowInfo="rowInfo"
                       :readonly="readonly"></DistributionRoles>
  </qx-page>
  <q-modal v-model="modalVisible" :header="formInfo.id ? $t('Edit') : $t('Add')" :width="500" btnAlign="center"
           position="right" @beforeClose="beforeClose" @confirm="submitForm">
    <qx-form ref="UserCfg" v-model="formInfo" :option="formOption"></qx-form>
  </q-modal>
</template>

<script setup>
import { useQuasar } from 'quasar'
import { deleteAPI, postAPI, putAPI } from 'src/api'
import { i18n, toI18nName } from 'boot/i18n'
import { isAuth } from 'src/directives/v-auth.js'
import { yesOrNo } from 'src/enum'
import { createDialog, deepClone, valiEmail, valiPhone } from 'src/utils/utils'
import { computed, onMounted, reactive, ref } from 'vue'
import DistributionRoles from './DistributionRoles.vue'

const $q = useQuasar()
const orgTree = ref([])
const rowInfo = ref({})
const formInfo = ref({})
const postList = ref([])
const rolesList = ref([])
const UserCfg = ref(null)
const loading = ref(false)
const searchForm = ref({})
const UserRole = ref(null)
const pageVisible = ref(false)
const roleLoading = ref(false)
const modalVisible = ref(false)
const props = reactive({ label: toI18nName('orgNameZhCn'), children: 'childs' })

const isXS = computed(() => $q.screen.width < 850)
const isDisable = computed(() => selected => !selected || selected.length !== 1 || selected[0].sysInner === '1')
const readonly = computed(() => rowInfo.value.sysInner === '1' || !isAuth(['memberUser:save', 'memberUser:update']))
const UserStatus = computed(() => {
  return [{
    label: `${i18n.t('SystemCore.Inactive')}`, value: '0'
  }, {
    label: `${i18n.t('SystemCore.OnJob')}`, value: '1'
  }, {
    label: `${i18n.t('SystemCore.Departure')}`, value: '2'
  }, {
    label: `${i18n.t('Disable')}`, value: '3'
  }]
})
const searchOption = computed(() => {
  return {
    labelWidth: 70, searchSpan: 4,
    column: [{
      label: `${i18n.t('SystemCore.Name')}`, field: 'nickName'
    }, {
      label: `${i18n.t('SystemCore.SubjectionOrg')}`, field: 'orgId', type: 'tree', options: orgTree.value,
      props, search: isXS.value
    }, {
      label: `${i18n.t('SystemCore.Role')}`, field: 'roleId', type: 'select', page: true,
      dicUrl: '/auth/api/authRole/listAuthRole', props: { label: toI18nName('roleNameZhCn'), value: 'id' }
    }, {
      label: `${i18n.t('SystemCore.UserStatus')}`, field: 'userStatus', type: 'select', searchValue: '1',
      options: UserStatus.value
    }]
  }
})
const formOption = computed(() => {
  return {
    labelWidth: 100, searchLabelWidth: 70, selection: 'single', menuBtn: false, span: 22,
    column: [{
      label: `${i18n.t('Account')}`, field: 'loginName', required: true, slot: true, readonly: !!formInfo.value.id,
      rules: [val => (!!formInfo.value.id || /^[\da-zA-Z_.]{4,20}$/.test(val)) || `${i18n.t('VerifyTip1')}`],
      hint: `${i18n.t('CreateTip1')}`, minWidth: 80
    }, {
      label: `${i18n.t('SystemCore.Name')}`, field: 'nickName', required: true, minWidth: 80
    }, {
      label: `${i18n.t('SystemCore.SubjectionOrg')}`, field: 'orgId', type: 'tree', options: orgTree.value,
      props, search: false, required: true, change: val => getPost(val),
      format: (_, row) => row[toI18nName('orgNameZhCn')], minWidth: 80
    }, {
      label: `${i18n.t('SystemCore.SubjectionPosition')}`, field: 'postId', type: 'select', options: postList.value,
      props: { label: toI18nName('postNameZhCn'), value: 'id' }, search: false, required: true,
      format: (_, row) => row[toI18nName('postNameZhCn')], minWidth: 80
    }, {
      label: `${i18n.t('Mobile')}`, field: 'mobile', search: false,
      rules: [val => valiPhone(val) || `${i18n.t('VerifyTip1')}`], minWidth: 80
    }, {
      label: `${i18n.t('Email')}`, field: 'email', search: false, required: true,
      rules: [val => valiEmail(val) || `${i18n.t('VerifyTip1')}`], minWidth: 80
    }, {
      label: `${i18n.t('Password')}`, field: 'password', type: 'password', hide: true,
      hint: !formInfo.value.id ? `${i18n.t('UserTip')} (middol123)` : '', display: !formInfo.value.id,
      maxlength: 50, search: false, minWidth: 80
    }, {
      label: `${i18n.t('SystemCore.SubjectionCompany')}`, field: 'ourCompanyFlag', type: 'radio', search: false,
      value: '1', options: yesOrNo.value, required: true, align: 'center', useTag: true, minWidth: 80
    }, {
      label: `${i18n.t('BuiltIn')}`, field: 'sysInner', search: false, display: false, options: yesOrNo.value,
      align: 'center', useTag: true, minWidth: 80
    }, {
      label: `${i18n.t('SystemCore.UserStatus')}`, field: 'userStatus', type: 'select', value: '1',
      options: UserStatus.value, required: true, align: 'center', minWidth: 80
    }, {
      label: `${i18n.t('Remarks')}`, field: 'remark', type: 'textarea', search: false, minWidth: 120, maxlength: 200
    }]
  }
})

const getOrgTree = () => {
  loading.value = true
  postAPI('/member/api/memberOrg/listTree', {}, data => {
    orgTree.value = data
    loading.value = false
  }, () => (loading.value = false))
}
getOrgTree()

const handleCreate = () => {
  formInfo.value = {}
  modalVisible.value = true
}

const getPost = value => {
  if (!value) {
    postList.value = []
    formInfo.value.postId = ''
    return
  }
  const params = { pageSize: '-1' }
  params.andDynamicQueryItems = [{ criterion: 'andEqualTo', property: 'orgId', value }]
  postAPI('/member/api/memberPost/list', params, data => {
    postList.value = data.rows
    const index = data.rows.findIndex(el => el.id === formInfo.value.postId)
    if (index === -1) formInfo.value.postId = ''
  }, () => (postList.value = []))
}

const handleUpdate = row => {
  formInfo.value = deepClone(row)
  modalVisible.value = true
}

const formatSearchForm = () => {
  const params = { ...searchForm.value }
  params.andDynamicQueryItems = []
  if (params.nickName) {
    params.andKeywordLikeItem = { keyword: params.nickName, propertys: ['nickName'] }
    delete params.nickName
  }
  if (!params.userStatus) params.userStatus = 'ALL'
  if (params.orgId) {
    params.andDynamicQueryItems.push({ criterion: 'andEqualTo', property: 'orgId', value: params.orgId })
    delete params.orgId
  }
  return params
}

const remoteData = ref({ dicUrl: '/member/api/memberUser/list' })
onMounted(() => startSearch())

const handleDelete = row => {
  createDialog({ msg: `${i18n.t('DelTips')}` }, () => {
    deleteAPI(`/member/api/memberUser/${row.id}`, {}, () => startSearch())
  }, () => {})
}

const handleRole = row => {
  roleLoading.value = true
  const params = { pageSize: '-1' }
  params.andDynamicQueryItems = [{ criterion: 'andEqualTo', property: 'userId', value: row.id }]
  postAPI('/auth/api/authRole/listAuthRoleUser', params, data => {
    rolesList.value = data.rows.map(el => {
      return { id: el.roleId }
    })
    rowInfo.value = { ...row }
    roleLoading.value = false
    pageVisible.value = true
  }, () => {
    rolesList.value = []
    roleLoading.value = false
  })
}

const treeChange = target => {
  searchForm.value.orgId = target
  remoteData.value.params = formatSearchForm()
}

const beforeClose = () => {
  if (UserCfg.value) UserCfg.value.onReset()
  modalVisible.value = false
}

const startSearch = (_, done) => {
  remoteData.value.params = formatSearchForm()
  remoteData.value.clearSelected = true
  if (done) done()
}

const submitRole = done => UserRole.value && UserRole.value.submitRole(done)
const submitForm = mDone => {
  UserCfg.value.validate((form, done) => {
    const API = form.id ? putAPI : postAPI
    API('/member/api/memberUser', form, () => {
      startSearch()
      done()
      if (mDone) mDone()
    }, () => {
      done()
      if (mDone) mDone(false)
    })
  }, () => {
    if (mDone) mDone(false)
  })
}

</script>